package org.jeecg.modules.system.service.impl;


import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import jakarta.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.constant.enums.CmProjectEventEnum;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.system.vo.DictModel;
import org.jeecg.modules.system.entity.*;
import org.jeecg.modules.system.mapper.CmProjectMapper;
import org.jeecg.modules.system.service.*;
import org.jeecgframework.poi.excel.ExcelImportUtil;
import org.jeecgframework.poi.excel.entity.ImportParams;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Description: Clinical Management Status
 * @Author: jeecg-boot
 * @Date:   2022-09-20
 * @Version: V1.0
 */
@Service
public class CmProjectServiceImpl extends ServiceImpl<CmProjectMapper, CmProject> implements ICmProjectService {
    @Autowired
    private ISysDictService sysDictService;
    @Autowired
    private ICmProjectEventService cmProjectEventService;
    @Autowired
    private ICmProjectResourceMonthService cmProjectResourceMonthService;
    @Autowired
    private ICmProjectResourceMonthRoleService cmProjectResourceMonthRoleService;
    @Autowired
    private ISysUserService sysUserService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveWithSub(CmProject cmProject) {
        try {
            this.save(cmProject);
            if (!CollectionUtil.isEmpty(cmProject.getAddEvents())) {
                cmProject.getAddEvents().stream().forEach(el -> el.setProjectId(cmProject.getId()));
                cmProject.getAddEvents().stream().forEach(el -> el.setId(null));
                cmProjectEventService.saveBatch(cmProject.getAddEvents());
            }
        }catch (Exception e){
            if(e.getMessage().contains(CommonConstant.SQL_INDEX_UNIQ_PROJECTNAME_DELFLAG)){
                throw new JeecgBootException("Project Name Repeated!");
            }
            throw e;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void editWithSub(CmProject cmProject) {
        try {
            this.updateById(cmProject);
            if (!CollectionUtil.isEmpty(cmProject.getUpdateEvents())) {
                cmProjectEventService.updateBatchById(cmProject.getUpdateEvents());
            }
        }catch (Exception e){
            if(e.getMessage().contains(CommonConstant.SQL_INDEX_UNIQ_PROJECTNAME_DELFLAG)){
                throw new JeecgBootException("Project Name Repeated!");
            }
            throw e;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void editResourceWithSub(CmProject cmProject) {
        try{
            this.updateById(cmProject);
            CmProjectResourceMonth cmProjectResourceMonthParam = new CmProjectResourceMonth();
            cmProjectResourceMonthParam.setProjectId(cmProject.getId());
            QueryWrapper<CmProjectResourceMonth> cmProjectResourceMonthQueryWrapper = new QueryWrapper<>(cmProjectResourceMonthParam);
            List<CmProjectResourceMonth> cmProjectResourceMonthList = cmProjectResourceMonthService.list(cmProjectResourceMonthQueryWrapper);
            if(CollectionUtil.isEmpty(cmProjectResourceMonthList)){
                List<CmProjectResourceMonth> cmProjectResourceMonths = cmProject.getCmProjectResourceMonthList();
                if(!CollectionUtil.isEmpty(cmProjectResourceMonths)){
                    for (CmProjectResourceMonth cmProjectResourceMonth : cmProjectResourceMonths) {
                        cmProjectResourceMonth.setId(null);
                        cmProjectResourceMonth.setProjectId(cmProject.getId());
                        cmProjectResourceMonthService.save(cmProjectResourceMonth);
                        if(!CollectionUtil.isEmpty(cmProjectResourceMonth.getCmProjectResourceMonthRoleList())) {
                            for (CmProjectResourceMonthRole cmProjectResourceMonthRole : cmProjectResourceMonth.getCmProjectResourceMonthRoleList()) {
                                cmProjectResourceMonthRole.setId(null);
                                cmProjectResourceMonthRole.setProjectId(cmProject.getId());
                                cmProjectResourceMonthRole.setProjectResourceMonthId(cmProjectResourceMonth.getId());
                            }
                            cmProjectResourceMonthRoleService.saveBatch(cmProjectResourceMonth.getCmProjectResourceMonthRoleList());
                        }
                    }
                }
            }else {
                //先删除原来的
                List<String> deleteBatchIds = cmProjectResourceMonthList.stream().map(CmProjectResourceMonth::getId).collect(Collectors.toList());
                cmProjectResourceMonthService.removeByIds(deleteBatchIds);
                QueryWrapper<CmProjectResourceMonthRole> cmProjectResourceMonthRoleQueryWrapper = new QueryWrapper<>();
                cmProjectResourceMonthRoleQueryWrapper.in("project_resource_month_id",deleteBatchIds);
                cmProjectResourceMonthRoleService.remove(cmProjectResourceMonthRoleQueryWrapper);

                List<CmProjectResourceMonth> cmProjectResourceMonths = cmProject.getCmProjectResourceMonthList();
                if(!CollectionUtil.isEmpty(cmProjectResourceMonths)){
                    for (CmProjectResourceMonth cmProjectResourceMonth : cmProjectResourceMonths) {
                        cmProjectResourceMonth.setId(null);
                        cmProjectResourceMonth.setProjectId(cmProject.getId());
                        cmProjectResourceMonthService.save(cmProjectResourceMonth);
                        if(!CollectionUtil.isEmpty(cmProjectResourceMonth.getCmProjectResourceMonthRoleList())) {
                            for (CmProjectResourceMonthRole cmProjectResourceMonthRole : cmProjectResourceMonth.getCmProjectResourceMonthRoleList()) {
                                cmProjectResourceMonthRole.setId(null);
                                cmProjectResourceMonthRole.setProjectId(cmProject.getId());
                                cmProjectResourceMonthRole.setProjectResourceMonthId(cmProjectResourceMonth.getId());
                            }
                            cmProjectResourceMonthRoleService.saveBatch(cmProjectResourceMonth.getCmProjectResourceMonthRoleList());
                        }
                    }
                }

            }

        }catch (Exception e){
            if(e.getMessage().contains(CommonConstant.SQL_INDEX_UNIQ_PROJECTID_MONTH)){
                throw new JeecgBootException("Month Repeated!");
            }
            if(e.getMessage().contains(CommonConstant.SQL_INDEX_UNIQ_PROJECTID_MONTH_ROLE_STAFF)){
                throw new JeecgBootException("Role,Staff Repeated!");
            }
            throw e;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer importExcel(HttpServletRequest request) {
        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
        Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
        for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
            // 获取上传文件对象
            MultipartFile file = entity.getValue();
            ImportParams params = new ImportParams();
            params.setHeadRows(2);
            params.setSheetNum(1);
            params.setNeedSave(false);
            try {
                List<CmProject> cmProjectList = ExcelImportUtil.importExcel(file.getInputStream(),CmProject.class,params);
                List<String> statusList = sysDictService.queryDictItemsByCode("cm_project_status").stream().map(DictModel::getValue).collect(Collectors.toList());
                List<String> typeList = sysDictService.queryDictItemsByCode("cm_project_type").stream().map(DictModel::getValue).collect(Collectors.toList());
                List<String> systemList = sysDictService.queryDictItemsByCode("cm_project_system").stream().map(DictModel::getValue).collect(Collectors.toList());
                QueryWrapper<SysUser> queryWrapper = QueryGenerator.initQueryWrapper(new SysUser(), request.getParameterMap());
                List<String> dmlUserNameList = sysUserService.list(queryWrapper).stream().map(SysUser::getUsername).collect(Collectors.toList());

                List<String> errorMessageList = new ArrayList<>();
                if(!CollectionUtil.isEmpty(cmProjectList)){
                    for (int i = 1; i <= cmProjectList.size(); i++) {
                        String lineMessage = "Line "+(i+2)+",";
                        String errorMessage = null;
                        CmProject cmProject = cmProjectList.get(i-1);
                        if(StringUtils.isEmpty(cmProject.getProjectName())){
                            errorMessage = lineMessage+ "Name can not be blank！";
                            errorMessageList.add(errorMessage);
                            continue;
                        }
                        if(StringUtils.isEmpty(cmProject.getDmlName())){
                            errorMessage = lineMessage+ "DML can not be blank！";
                            errorMessageList.add(errorMessage);
                            continue;
                        }else {
                            if(!dmlUserNameList.contains(cmProject.getDmlName())){
                                errorMessage = lineMessage+ "DML does not exist！";
                                errorMessageList.add(errorMessage);
                                continue;
                            }
                        }
                        if(StringUtils.isEmpty(cmProject.getStatus())){
                            errorMessage = lineMessage+ "Status can not be blank！";
                            errorMessageList.add(errorMessage);
                            continue;
                        }else {
                            if(!statusList.contains(cmProject.getStatus())){
                                errorMessage = lineMessage+ "Status "+cmProject.getStatus()+" does not exist！";
                                errorMessageList.add(errorMessage);
                                continue;
                            }
                        }
                        if(StringUtils.isEmpty(cmProject.getType())){
                            errorMessage = lineMessage+ "Type can not be blank！";
                            errorMessageList.add(errorMessage);
                            continue;
                        }else {
                            if(!typeList.contains(cmProject.getType())){
                                errorMessage = lineMessage+ "Type "+cmProject.getType()+" does not exist！";
                                errorMessageList.add(errorMessage);
                                continue;
                            }
                        }
                        if(StringUtils.isEmpty(cmProject.getSystem())){
                            errorMessage = lineMessage+ "System can not be blank！";
                            errorMessageList.add(errorMessage);
                            continue;
                        }else {
                            List<String> systems = Arrays.asList(cmProject.getSystem().split(","));
                            boolean systemError = true;
                            for (String system : systems) {
                                if(!systemList.contains(system)){
                                    errorMessage = lineMessage+ "System "+cmProject.getSystem()+" does not exist！";
                                    errorMessageList.add(errorMessage);
                                    systemError = false;
                                }
                            }
                            if(!systemError){
                                continue;
                            }
                        }
                        if(StringUtils.isEmpty(cmProject.getCompound())){
                            errorMessage = lineMessage+ "Drug & Client can not be blank！";
                            errorMessageList.add(errorMessage);
                            continue;
                        }
                    }
                }
                if(CollectionUtil.isEmpty(errorMessageList)){
                    for (int i = 1; i <= cmProjectList.size(); i++) {
                        CmProject cmProject = cmProjectList.get(i-1);
                        this.save(cmProject);
                        List<CmProjectEvent> cmProjectEventList = new ArrayList<>();
                        CmProjectEvent crfFinalEvent = cmProject.getCrfFinalEvent();
                        CmProjectEvent dmpSignOffEvent = cmProject.getDmpSignOffEvent();
                        CmProjectEvent approvalSignedEvent = cmProject.getApprovalSignedEvent();
                        CmProjectEvent sivDateEvent = cmProject.getSivDateEvent();
                        CmProjectEvent fpfvEvent = cmProject.getFpfvEvent();
                        CmProjectEvent lplvEvent = cmProject.getLplvEvent();
                        CmProjectEvent dataTransferEvent = cmProject.getDataTransferEvent();
                        CmProjectEvent sapSignOffEvent = cmProject.getSapSignOffEvent();
                        CmProjectEvent databaseLockEvent = cmProject.getDatabaseLockEvent();
                        CmProjectEvent dmrSignOffEvent = cmProject.getDmrSignOffEvent();
                        CmProjectEvent decommissionEvent = cmProject.getDecommissionEvent();
                        crfFinalEvent.setProjectId(cmProject.getId());
                        crfFinalEvent.setEvent(CmProjectEventEnum.CRF_OR_ACRF_FINAL.getDesc());
                        dmpSignOffEvent.setProjectId(cmProject.getId());
                        dmpSignOffEvent.setEvent(CmProjectEventEnum.DMP_SIGN_OFF.getDesc());
                        approvalSignedEvent.setProjectId(cmProject.getId());
                        approvalSignedEvent.setEvent(CmProjectEventEnum.GO_LIVE_STATUS.getDesc());
                        sivDateEvent.setProjectId(cmProject.getId());
                        sivDateEvent.setEvent(CmProjectEventEnum.SIV_DATE.getDesc());
                        fpfvEvent.setProjectId(cmProject.getId());
                        fpfvEvent.setEvent(CmProjectEventEnum.FPFV.getDesc());
                        lplvEvent.setProjectId(cmProject.getId());
                        lplvEvent.setEvent(CmProjectEventEnum.LPLV.getDesc());
                        dataTransferEvent.setProjectId(cmProject.getId());
                        dataTransferEvent.setEvent(CmProjectEventEnum.DATA_TRANSFER.getDesc());
                        sapSignOffEvent.setProjectId(cmProject.getId());
                        sapSignOffEvent.setEvent(CmProjectEventEnum.SAP_SIGN_OFF.getDesc());
                        databaseLockEvent.setProjectId(cmProject.getId());
                        databaseLockEvent.setEvent(CmProjectEventEnum.DATABASE_LOCK.getDesc());
                        dmrSignOffEvent.setProjectId(cmProject.getId());
                        dmrSignOffEvent.setEvent(CmProjectEventEnum.DMR_SIGN_OFF.getDesc());
                        decommissionEvent.setProjectId(cmProject.getId());
                        decommissionEvent.setEvent(CmProjectEventEnum.DECOMMISSION.getDesc());
                        cmProjectEventList.add(crfFinalEvent);
                        cmProjectEventList.add(dmpSignOffEvent);
                        cmProjectEventList.add(approvalSignedEvent);
                        cmProjectEventList.add(sivDateEvent);
                        cmProjectEventList.add(fpfvEvent);
                        cmProjectEventList.add(lplvEvent);
                        cmProjectEventList.add(dataTransferEvent);
                        cmProjectEventList.add(sapSignOffEvent);
                        cmProjectEventList.add(databaseLockEvent);
                        cmProjectEventList.add(dmrSignOffEvent);
                        cmProjectEventList.add(decommissionEvent);
                        cmProjectEventService.saveBatch(cmProjectEventList);
                    }
                    return cmProjectList.size();
                }else {
                    throw new JeecgBootException("ErrorMessage:"+ JSONObject.toJSONString(errorMessageList)+"！");
                }
            } catch (Exception e) {
                log.error(e.getMessage(), e);
                String exceptionMessage = "Fail";
                if(e.getMessage().contains(CommonConstant.SQL_INDEX_UNIQ_PROJECTNAME_DELFLAG)){
                    exceptionMessage+=",Project Name Repeat！";
                }else if(e instanceof JeecgBootException){
                    exceptionMessage+=(","+e.getMessage()+"！");
                }else {
                    exceptionMessage+="！";
                }
                throw new JeecgBootException(exceptionMessage);
            } finally {
                try {
                    file.getInputStream().close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return 0;
    }
}
